/********************************************************************************
* @file    app_power.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-06-09
* @brief   电源管理 USB和充电实时检测
********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "app_power.h"
#include "bsp_gpio.h"
#include "os_api.h"

/* Private Includes ----------------------------------------------------------*/
#include "ls_gpio.h"
#include "ls_syscfg.h"
/* Private Variables ---------------------------------------------------------*/
__attribute__((aligned(4))) power_info_t power_info = {0};
/* Public Function Prototypes -----------------------------------------------*/
/**
 * @brief  得到power_info结构体指针
 */
void* get_power_info_p(void)
{
    return &power_info;
}

/**
 * @brief  得到power_info.bat_info结构体指针
 */
void* get_bat_info_p(void)
{
    return &(power_info.bat_info);
}

/**
 * @brief  获得usb状态 (非实时)
 * @retval 0--未插入 1--插入
 */
bool get_usb_state(void)
{
    return power_info.usb_state;
}

/**
 * @brief  设置usb状态
 * @param  state: 0--未插入 1--插入
 */
void set_usb_state(bool state)
{
    power_info.usb_state = state;
}

/**
 * @brief  获得charge状态 (非实时)
 * @retval 0--未充满 1--充满
 */
bool get_charge_state(void)
{
    return power_info.charge_state;
}

/**
 * @brief  设置usb状态
 * @param  state: 0--未充满 1--充满
 */
void set_charge_state(bool state)
{
    power_info.charge_state = state;
}

/**
 * @brief  设置电池soc值
 * @param  soc: 0-100
 */
void set_bat_soc_val(uint8_t soc)
{
    if (soc <= 100)
    {
        if (power_info.bat_info.bat_sos != soc)
        {
            power_info.bat_info.bat_sos = soc;
            set_bat_whether_write(true);
        }
    }
}

/**
 * @brief  增加电池soc值 a += b
 * @param  soc: 0-100
 */
void increment_bat_soc_val(uint8_t soc)
{
    if (power_info.bat_info.bat_sos + soc < 100)
    {
        power_info.bat_info.bat_sos += soc;
        if (soc != 0)
        {
            set_bat_whether_write(true);
        }
    }
    else
    {
        if (power_info.bat_info.bat_sos != 100)
        {
            power_info.bat_info.bat_sos = 100;
            set_bat_whether_write(true);
        }
    }
}

/**
 * @brief  减少电池soc值 a -= b
 * @param  soc: 0-100
 */
void reduce_bat_soc_val(uint8_t soc)
{
    if (power_info.bat_info.bat_sos - soc > 0)
    {
#if LS_BAT_SOC_TYPE != 0
        if (power_info.bat_info.bat_sos == 99)
        {
            power_info.bat_info.bat_sos = 100;
        }
#endif
        power_info.bat_info.bat_sos -= soc;
        //LOG_D("<DEBUG> reduce_bat_soc_val:%d%\r\n", soc);
        if (soc != 0)
        {
            set_bat_whether_write(true);
        }
    }
    else
    {
        if (power_info.bat_info.bat_sos != 0)
        {
            power_info.bat_info.bat_sos = 0;
            set_bat_whether_write(true);
        }
    }
}

/**
 * @brief  得到电池soc值 (非实时)
 * @param  soc: 0-100
 */
uint8_t get_bat_soc_val(void)
{
    return power_info.bat_info.bat_sos;
}

/**
 * @brief  得到电池充满时的电压值
 * @retval 0-4500
 */
uint16_t get_bat_full_vol_val(void)
{
    return power_info.bat_info.charge_full_vol_val;
}

/**
 * @brief  设置电池充满时的电压值
 * @retval 0-4500
 */
void set_bat_full_vol_val(uint16_t voltage)
{
    if (power_info.bat_info.charge_full_vol_val != voltage)
    {
        set_bat_whether_write(true);
        power_info.bat_info.charge_full_vol_val = voltage;
    }
}

/**
 * @brief  获得电池状态 (非实时)
 * @retval power_bat_state_t
 */
power_bat_state_t get_bat_state(void)
{
    return power_info.bat_info.bat_state;
}

/**
 * @brief  设置电池状态
 * @param  state: power_bat_state_t
 */
void set_bat_state(power_bat_state_t state)
{
    if (power_info.bat_info.bat_state != state)
    {
        set_bat_whether_write(true);
        if (power_info.bat_info.bat_state > state)
        {
            power_info.bat_info.bat_state --;
        }
        else
        {
            power_info.bat_info.bat_state ++;
        }
    }
}

/**
 * @brief  获得电池电压 (非实时)
 * @retval power_bat_state_t
 */
uint16_t get_bat_vol(void)
{
    return power_info.bat_info.bat_vol;
}

/**
 * @brief  设置电池电压
 * @param  voltage: 电压值
 */
void set_bat_vol(uint16_t vol)
{
    power_info.bat_info.bat_vol = vol;
}

/**
 * @brief  自减电池电压 a -= b
 * @param  voltage: 自减值
 */
void reduce_bat_vol(uint16_t vol)
{
    power_info.bat_info.bat_vol -= vol;
}

/**
 * @brief  设置电池电压偏移值
 * @param  offset: 偏移值+-127
 */
void set_bat_vol_offset(short offset)
{
    if (power_info.bat_info.bat_vol_offset != offset)
    {
        set_bat_whether_write(true);
        power_info.bat_info.bat_vol_offset = offset;
    }
}

/**
 * @brief  获得电池电压偏移值 (非实时)
 * @retval 偏移值+-127
 */
short get_bat_vol_offset(void)
{
    return power_info.bat_info.bat_vol_offset;
}

/**
 * @brief  获得电池数据是否需要写入
 * @retval 0--不需要写入 1--需要写入
 */
bool get_bat_whether_write(void)
{
    return power_info.bat_info.write_in;
}

/**
 * @brief  设置电池数据是否需要写入
 * @param  state: 0--不需要写入 1--需要写入
 */
void set_bat_whether_write(bool state)
{
    power_info.bat_info.write_in = state;
}

/**
 * @brief  [电源管理] 判断当前电池状态
 * @note   举例：当前80%，充电时，状态灯亮前面4个，第五个闪烁。不充电时，亮5个灯。
 * @param  bat_soc: 电量%
 * @param  usb_state: USB状态
 * @retval 返回电池容量状态
 */
power_bat_state_t app_power_get_bat_state(uint16_t bat_soc, uint8_t usb_state)
{
    if (bat_soc == LS_POWER_FULL_BATTERY_THRESHOLD)
    {
        return POWER_FULL_BATTERY;
    }
    else if (bat_soc >= LS_POWER_HIGH_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_HIGH_BATTERY;
        }
        else
        {
            return POWER_FULL_BATTERY;
        }
    }
    else if (bat_soc >= LS_POWER_MIDDLE_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_MIDDLE_BATTERY;
        }
        else
        {
            return POWER_HIGH_BATTERY;
        }
    }
    else if (bat_soc >= LS_POWER_LOW_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_LOW_BATTERY;
        }
        else
        {
            return POWER_MIDDLE_BATTERY;
        }
    }
    else if (bat_soc >= LS_POWER_LOW_LOW_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_LOW_LOW_BATTERY;
        }
        else
        {
            return POWER_LOW_BATTERY;
        }
    }
    else if (bat_soc >= LS_POWER_VERY_LOW_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_VERY_LOW_BATTERY;
        }
        else
        {
            return POWER_LOW_LOW_BATTERY;
        }
    }
    else if (bat_soc >= LS_POWER_SHUTDOWN_BATTERY_THRESHOLD)
    {
        if (usb_state)
        {
            return POWER_SHUTDOWN_BATTERY;
        }
        else
        {
            return POWER_VERY_LOW_BATTERY;
        }
    }
    else
    {
        return POWER_SHUTDOWN_BATTERY;
    }
}

/**
 * @brief  [通过充电IC单个引脚逻辑判断 或者直接引脚判断] 得到充电状态
 * @retval 范围：[0,2] POWER_NOT_CHARGE = 0 (未充电),  POWER_CHARGING = 1(充电中),  POWER_CHARGE_DONE = 2 (充满)
 */
power_charge_state_t app_power_get_charge_state(void)
{
#if defined(USB_PORT) && defined(USB_PIN) && defined(CHARGE_PORT) && defined(CHARGE_PIN)
    // USB插入，且未充满
    if (get_io_ste(USB_PORT, USB_PIN) == LS_USB_PIN_INPUT_STATE &&
        get_io_ste(CHARGE_PORT, CHARGE_PIN) == !LS_CHARGE_PIN_DONE_STATE)
    {
        return POWER_CHARGING;
    }
    // USB插入，且充满
    else if (get_io_ste(USB_PORT, USB_PIN) == LS_USB_PIN_INPUT_STATE &&
             get_io_ste(CHARGE_PORT, CHARGE_PIN) == LS_CHARGE_PIN_DONE_STATE)
    {
        return POWER_CHARGE_DONE;
    }
    else
    {
        return POWER_NOT_CHARGE;
    }
#else
    return POWER_NOT_CHARGE;
#endif
}

/**
 * @brief  [通过充电IC单个引脚逻辑判断 或者直接引脚判断] 得到usb状态 (实时获取)
 * @retval 0--拔出  1--插入
 */
bool app_power_get_usb_state(void)
{
#if defined(USB_PORT) && defined(USB_PIN)
    if (get_io_ste(USB_PORT, USB_PIN) == LS_USB_PIN_INPUT_STATE)
    {
        return true;
    }
    else
    {
        return false;
    }
#else
    return false;
#endif
}

/**
 * @brief  [通过充电IC两个引脚逻辑判断] 得到usb状态 (实时获取)
 * @retval 0--拔出  1--插入
 */
bool app_power_get_usb_state2(void)
{
#if defined(USB_PORT) && defined(USB_PIN) && defined(CHARGE_PORT) && defined(CHARGE_PIN)
    if ((get_io_ste(USB_PORT, USB_PIN) == !LS_USB_PIN_INPUT_STATE) && (get_io_ste(CHARGE_PORT, CHARGE_PIN) == !LS_CHARGE_PIN_DONE_STATE))
    {
        return false;
    }
    else if ((get_io_ste(USB_PORT, USB_PIN) == LS_USB_PIN_INPUT_STATE) && (get_io_ste(CHARGE_PORT, CHARGE_PIN) == LS_CHARGE_PIN_DONE_STATE))
    {
        return false;
    }
    else
    {
        return true;
    }
#else
    return false;
#endif
}

/**
 * @brief  [通过充电IC两个引脚逻辑判断] 得到充电状态
 * @retval 范围：[0,2]  注释：0--未充电  1--充电中  2--充满
 */
power_charge_state_t app_power_get_charge_state2(void)
{
#if defined(USB_PORT) && defined(USB_PIN) && defined(CHARGE_PORT) && defined(CHARGE_PIN)
    // USB插入，且未充满
    if (get_io_ste(USB_PORT, USB_PIN) == LS_USB_PIN_INPUT_STATE &&
        get_io_ste(CHARGE_PORT, CHARGE_PIN) == !LS_CHARGE_PIN_DONE_STATE)
    {
        return POWER_CHARGING;
    }
    // USB插入，且充满
    else if (get_io_ste(USB_PORT, USB_PIN) == !LS_USB_PIN_INPUT_STATE &&
             get_io_ste(CHARGE_PORT, CHARGE_PIN) == LS_CHARGE_PIN_DONE_STATE)
    {
        return POWER_CHARGE_DONE;
    }
    else
    {
        return POWER_NOT_CHARGE;
    }
#else
    return POWER_NOT_CHARGE;
#endif
}
